<template>
  <a-modal
    :title="getTitle()"
    :visible="visible"
    :confirm-loading="confirmLoading"
    width="900px"
    okText="保存"
    @ok="onSubmit()"
    @cancel="handleCancel"
  >
    <a-form-model ref="formRef" :rules="rules" :model="form" :label-col="{ span: 3 }" :wrapper-col="{ span: 21 }">
      <a-form-model-item label="流程定义" prop="flowName">
        <a-input v-model="form.flowName" style="width: 60%" placeholder="请输入流程定义" />
      </a-form-model-item>
      <a-form-model-item label="适用类型">
        <span>{{ type == 1 ? '研究者费用' : '受试者费用' }} </span>
      </a-form-model-item>
      <a-descriptions title="流程编辑"></a-descriptions>
      <a-form-model-item label="审批人">
        <!-- 动态渲染申请人list start -->
        <a-row :gutter="14" :key="index" v-for="(i, index) in renderApproverList">
          <a-col :span="6" v-if="!i.isMain">
            <a-select v-model="i.applyType" placeholder="请选择费用科目">
              <a-select-option
                v-for="j in expenseList"
                :value="j.applyType"
                :key="j.applyType"
              >
                {{ j.applyType }}
              </a-select-option>
            </a-select>
          </a-col>
          <a-col :span="6">
            <a-select v-model="i.roleId" placeholder="请选择审批人" @change="handleRoleChange(index, 0)">
              <template v-for="j in rolesList">
                <a-select-option :value="j.roleId" :key="j.roleId">{{ j.roleName }}</a-select-option>
              </template>
            </a-select>
          </a-col>
          <a-col :span="6" v-if="canChooseRoleId(i.roleId)">
            <a-select mode="multiple" v-model="i.ids" placeholder="请选择账户">
              <a-select-option v-for="j in accountObj[i.roleId]" :value="j.approveId" :key="j.approveId">{{ j.name }}</a-select-option>
            </a-select>
          </a-col>
          <a-col :span="1" class="action">
            <a-tooltip placement="bottomLeft" title="添加审批人">
              <a-popconfirm
                title="请选择节点类型"
                okText="分支节点"
                cancelText="主节点"
                @confirm="addNode(false, index)"
                @cancel="addNode(true, index)"
              >
                <a-button type="link" icon="plus-square" size="small" class="action-btn"></a-button>
              </a-popconfirm>
            </a-tooltip>
            <a-tooltip placement="topLeft" title="删除当前行">
              <a-button type="link" icon="minus-square" size="small" @click="clickRemove(index)" class="action-btn"></a-button>
            </a-tooltip>
          </a-col>
        </a-row>
        <a-popconfirm
          v-if="renderApproverList.length === 0"
          title="请选择节点类型"
          okText="分支节点"
          cancelText="主节点"
          @confirm="addNode(false, 0)"
          @cancel="addNode(true, 0)"
        >
          <a-button type="dashed" block>
            <a-icon type="plus" /> 添加审批人
          </a-button>
        </a-popconfirm>
        <!-- 动态渲染申请人list end -->
      </a-form-model-item>
      <a-form-model-item label="抄送人">
        <template v-for="(i, index) in renderCcList">
          <a-row :gutter="14" :key="index">
            <a-col :span="6">
              <a-select v-model="i.roleId" placeholder="请选择抄送人" @change="handleRoleChange(index, 1)">
                <a-select-option v-for="j in rolesList" :value="j.roleId" :key="j.roleId">{{ j.roleName }}</a-select-option>
              </a-select>
            </a-col>
            <a-col :span="6" v-if="canChooseRoleId(i.roleId)">
              <a-select mode="multiple" v-model="i.ids" placeholder="请选择账户">
                <a-select-option v-for="j in accountObj[i.roleId]" :value="j.approveId" :key="j.approveId">{{ j.name }}</a-select-option>
              </a-select>
            </a-col>
            <a-col :span="1">
              <a-tooltip placement="topLeft" title="删除当前行">
                <a-button type="link" icon="delete" size="small" @click="clickRemoveRow(index)"></a-button>
              </a-tooltip>
            </a-col>
          </a-row>
        </template>
        <!-- 添加审批节点 -->
        <a-button type="dashed" @click="addCcNode()" block>
          <a-icon type="plus" /> 添加抄送人
        </a-button>
      </a-form-model-item>
      <div style="color: red;" v-if="isEdit">注：如在有未审核的审批流程的情况下，编辑审批流程会导致审批流程失效，请谨慎修改</div>
    </a-form-model>
  </a-modal>
</template>
<script>
import monitor from '@/utils/monitor'
import subjectModal from '@/monitor/views/overview/detail/responsible/components/approval/subjectModal.js'
import { getList } from '@/api/overview/cost'
import { getRolesList, getAccountList, addApproval, updateApproval } from '@/api/overview/approval'
import cloneDeep from 'lodash.clonedeep'
import ApprovalNode from './approvalNode'

const watch = monitor(subjectModal)

export default {
  props: {
    visible: { // 显示隐藏
      type: Boolean,
      dafault: true
    },
    isEdit: { // 是否是编辑
      type: Boolean,
      dafault: false
    },
    type: { // 1受试者 2研究者
      type: Number,
      default: 1
    }
  },
  data () {
    return {
      confirmLoading: false,
      form: {
        flowName: '',
        type: ''
      },
      expenseList: [],
      rolesList: [],
      rolesMap: {},
      renderApproverList: [],
      renderCcList: [],
      rules: {
        flowName: [{ required: true, message: '请输入流程定义', trigger: 'change' }]
      },
      accountObj: {}
    }
  },
  watch: {
    visible: {
      immediate: true,
      handler (val) {
        val && this.getExpenseList()
      }
    }
  },
  created () {
    this.getRolesList()
  },
  methods: watch({
    canChooseRoleId (roleId) {
      if (!roleId) return false
      return !['PI', 'CRC'].includes(this.rolesMap[roleId].nameUpper)
    },
    getTitle () {
      let title = ''
      if (this.type === 1) {
        title = this.isEdit ? '编辑研究者审批流程' : '新增研究者审批流程'
      } else {
        title = this.isEdit ? '编辑受试者审批流程' : '新增受试者审批流程'
      }
      return title
    },
    // 初始化数据
    initData (e) {
      if (e) {
        console.log('e', e)
        this.form.id = e.id
        this.form.flowName = e.flowName
        this.form.type = e.type
        const editRoles = []
        this.renderApproverList = []
        if (e.nodeList && e.nodeList.length) {
          let approverList = cloneDeep(e.nodeList)
          approverList = approverList.filter(v => v.nodeType !== 2)
          approverList.forEach(item => {
            item.isMain = !item.parentCode
            item.ids = item.processorId ? item.processorId.split(',').map(item => parseInt(item)) : []
            this.renderApproverList.push(item)
            item.roleId && this.getAccountList(item.roleId)
          })
          // 删除最后一条数据
          this.renderApproverList.pop()
          this.renderApproverList.forEach(item => {
            if (editRoles.indexOf(item.roleId) === -1) {
              editRoles.push(item.roleId)
            }
          })
        }
        const ccCopy = JSON.parse(e.cc)
        this.renderCcList = []
        ccCopy.forEach(item => {
          item.ids = (item.approveId != null && item.approveId.length > 0) ? item.approveId.split(',').map(item => parseInt(item)) : []
          this.renderCcList.push(item)
          if (editRoles.indexOf(item.roleId) === -1) {
            editRoles.push(item.roleId)
          }
        })
        editRoles.forEach(item => {
          this.getAccountList(item)
        })
      }
    },
    async getRolesList () {
      const res = await getRolesList({ proId: this.$route.query.id })
      if (res && res.length) {
        this.rolesList = []
        res.forEach(item => {
          this.rolesMap[item.id] = { ...item, nameUpper: item.name.toUpperCase() }
          this.rolesList.push({
            roleId: item.id,
            roleName: item.name,
            code: item.code
          })
        })
      }
    },
    async getExpenseList () {
      const res = await getList({
        proId: this.$route.query.id,
        pageSize: 99,
        pageNumber: 1,
        type: this.type,
        status: 1
      })
      this.expenseList = res.content.filter(v => v.defaulted)
    },
    // 获取账户列表
    async getAccountList (roleId) {
      const res = await getAccountList({ proId: this.$route.query.id, roleId: roleId })
      if (res && res.length) {
        res.forEach(item => {
          // 有 approveNo 取 approveNo
          item.ids = (item.approveId != null && item.approveId.length > 0) ? item.approveId.split(',').map(item => parseInt(item)) : []
        })
      }
      this.$set(this.accountObj, roleId, res)
    },
    /**
     * @description 手动新增审批节点
     * @param isMain 是否主节点
     * @param index index
     */
    addNode (isMain, index) {
      this.renderApproverList = [
        ...this.renderApproverList.slice(0, index + 1),
        {
          isMain,
          approveId: undefined,
          applyType: undefined,
          approveType: '',
          roleId: undefined,
          roleName: '',
          ids: []
        },
        ...this.renderApproverList.slice(index + 1)
      ]
    },
    // 手动新增抄送人节点
    addCcNode () {
      this.renderCcList.push(
        {
          approveId: null,
          applyType: null,
          approveType: '',
          roleId: null,
          roleName: '',
          ids: []
        }
      )
    },
    // 点击删除审批人当前行
    clickRemove (index) {
      this.renderApproverList.splice(index, 1)
      this.$forceUpdate()
    },
    // 点击删除抄送人当前行
    clickRemoveRow (index) {
      // const newList = this.renderCcList.filter(item => item.id !== row.id)
      this.renderCcList.splice(index, 1)
      this.$forceUpdate()
    },
    // 审批人(0)/抄送人(1) 角色下拉改变 val判断审批还是抄送
    handleRoleChange (index, val) {
      let target = {}
      if (!val) {
        target = this.renderApproverList[index]
      } else {
        target = this.renderCcList[index]
      }
      const roleObj = this.rolesList.find(item => item.roleId === target.roleId)
      target.roleName = roleObj.roleName
      target.roleId = roleObj.roleId
      target.roleCode = roleObj.code
      // 清空 账户数据
      target.approveType = ''
      target.approveId = ''
      target.ids = []
      this.getAccountList(target.roleId)
    },
    // 审批人(0)/抄送人(1) 账户下拉改变 （将账户的approveId(下拉框已双向绑定)、approveType 保存到当前行）
    handleAccountChange (index, val) {
      let target = {}
      if (!val) {
        target = this.renderApproverList[index]
      } else {
        target = this.renderCcList[index]
      }
      const roleObj = this.accountObj[target.roleId].find(item => item.ids === target.ids)
      target.approveType = roleObj.approveType
      this.$forceUpdate()
    },
    // 点击确定进行保存
    onSubmit () {
      this.$refs.formRef.validate(valid => {
        if (valid) {
          this.checkData()
        }
      })
    },
    // 校验是否有审批或抄送
    checkData () {
      if (this.renderApproverList.length === 0) {
        this.$message.error('请添加审批人')
        return false
      }

      let hasDuplicateRole = false
      let hasDuplicateApplyType = false
      this.renderApproverList.forEach(item => {
        const applyTypeFilter = this.renderApproverList.filter(v => v.applyType && v.applyType === item.applyType)
        hasDuplicateApplyType = applyTypeFilter.length > 1
        // 主节点不可重复
        if (!item.isMain) return
        const filterArr = this.renderApproverList.filter(filterItem => filterItem.roleId === item.roleId && filterItem.isMain)
        hasDuplicateRole = filterArr.length > 1
      })

      if (hasDuplicateApplyType) {
        this.$message.error('费用科目不能重复')
        return false
      }

      if (hasDuplicateRole) {
        this.$message.error('主节点不可选择重复的角色')
        return false
      }

      if (this.renderApproverList.some(v => !v.roleId)) {
        this.$message.error('请选择审批角色')
        return
      }

      if (this.renderApproverList.some(v => !v.isMain && !v.applyType)) {
        this.$message.error('请为分支节点选择费用科目')
        return
      }

      let hasCcDuplicateRole = false
      this.renderCcList.forEach(item => {
        const filterArr = this.renderCcList.filter(filterItem => filterItem.roleId === item.roleId)
        if (filterArr.length > 1) {
          hasCcDuplicateRole = true
        }
      })
      if (hasCcDuplicateRole) {
        this.$message.error('抄送人不可选择重复的角色')
        return false
      }
      // 去重校验
      this.handleData()
    },
    // 处理要上传的数据
    handleData () {
      const flowNode = new ApprovalNode(this.renderApproverList, this.$route.query.id).getNodes()

      // 抄送人数据
      const ccList = []
      for (let i = 0; i < this.renderCcList.length; i++) {
        const { approveId, approveType, roleId, roleName, ids } = { ...this.renderCcList[i] }
        const obj = { approveId, approveType, roleId, roleName }
        obj.approveId = (ids != null && ids.length > 0) ? ids.join(',') : ''
        obj.roleCode = this.rolesMap[roleId] ? this.rolesMap[roleId].code : ''
        // 审批到 账号/角色    1：账号  2：角色
        obj.type = (ids != null && ids.length > 0) ? 1 : 2
        ccList.push(obj)
      }
      const req = {
        proId: this.$route.query.id,
        type: this.type,
        flowName: this.form.flowName,
        cc: JSON.stringify(ccList),
        flowNode: JSON.stringify(flowNode)
      }
      console.log(flowNode)
      this.addApproval(req)
    },
    // 发起添加请求 走新增/编辑接口
    addApproval (data) {
      if (!this.isEdit) {
        this.confirmLoading = true
        addApproval({ ...data })
          .then(res => {
            this.confirmLoading = false
            this.$message.success('流程信息已成功保存')
            this.handleCancel()
          })
          .catch(() => {
            this.confirmLoading = false
          })
      } else {
        if (this.type === 1) {
          // 修改受试者审批埋点
          this.editSubjectPoint()
        } else {
          // 修改研究者审批埋点
          this.editResearchPoint()
        }
        this.confirmLoading = true
        updateApproval({
          ...data,
          id: this.form.id
        }).then(res => {
            this.confirmLoading = false
            this.$message.success('流程信息已成功保存')
            this.handleCancel()
          })
          .catch(() => {
            this.confirmLoading = false
          })
      }
    },
    // 点击取消关闭弹窗
    handleCancel () {
      this.resetForm()
      this.$emit('closeSubjectModal')
    },
    // 弹窗关闭重置表单
    resetForm () {
      this.$refs.formRef.resetFields()
      this.form = this.$options.data().form
      this.renderApproverList = []
      this.renderCcList = []
      this.$forceUpdate()
    },
    // 修改受试者审批埋点
    editSubjectPoint () {},
    // 修改研究者审批埋点
    editResearchPoint () {}
  })
}
</script>
<style scoped lang="less">
.action {
  display: flex;
  align-items: center;
  .action-btn {
    margin: 7px 5px 0;
  }
}
</style>
